from oauth2_provider.contrib.rest_framework import TokenHasScope

from rest_framework.exceptions import PermissionDenied as permDenied

from .permissions import CheckOptionPermission
from .permissions import get_queryset_perm, cur_other_perm

from .utils.create import create_model, update_every_table
from .utils.validate import validate_person

from prj001.models.geninfo import GeneralInfo


def viewset_decorator(serializer, obj=None, is_not_info=None):
    ''' the class decorator for every view of class '''
    def view_decorator(cls):
        class ViewSet(cls):
            permission_classes = [TokenHasScope, CheckOptionPermission]
            required_scopes = ['prj001']
            serializer_class = serializer

            def get_queryset(self):

                if obj == 'upload':
                    return get_queryset_perm(self)

                if is_not_info:
                    return get_queryset_perm(self, obj=obj, is_not_info=is_not_info)

                return get_queryset_perm(self, obj=obj)

            def create(self, request, *args, **kwargs):

                if obj == 'upload':
                    return super().create(request, *args, **kwargs)

                person_url = request.data.get('person', '/')

                get_url = person_url[::-1].split('/')
                try:
                    person_id = int(get_url[1][::-1])
                    gen_obj = GeneralInfo.objects.get(id=person_id)
                except GeneralInfo.DoesNotExist:
                    raise permDenied('无对应的一般信息')
                except Exception:
                    if person_url == '/':
                        raise permDenied('对不起, 不存在一般基本信息')
                    else:
                        raise permDenied('数据错误, 请重试')

                if gen_obj.is_checked == '审核通过':
                    raise permDenied(detail={'msg': '此条信息已经审核通过, 请勿操作; 如需修改, 请更改审核状态'})

                return super().create(request, *args, **kwargs)

            def update(self, request, *args, **kwargs):
                cur_other_perm(self)
                return super().update(request, *args, **kwargs)

            def destroy(self, request, *args, **kwargs):
                cur_other_perm(self)
                return super().destroy(request, *args, **kwargs)

        return ViewSet
    return view_decorator


def serializer_decorator(model_obj=None, type=None):
    ''' the class decorator for every decorator of class '''
    def inner_decorator(cls):
        class ViewSerializer(cls):

            class Meta:
                model = model_obj
                fields = '__all__'
                read_only_fields = ('owner', )

            def validate(self, value):
                return validate_person(value)

            def create(self, data):
                if type == 'cure_degree':
                    return create_model(self,
                                        data=data,
                                        obj=model_obj,
                                        tps='cure_degree')
                return create_model(self, data=data, obj=model_obj)

            def update(self, instance, data):
                if type == 'cure_degree':
                    return update_every_table(instance,
                                              data,
                                              tps='cure_degree')
                return update_every_table(instance, data)
        return ViewSerializer
    return inner_decorator


def moblie_serializer_decorator(model_obj):
    ''' the class decorator for every mobile decorator of class '''
    def inner_decorator(cls):
        class MViewSerializer(cls):

            class Meta:
                model = model_obj
                fields = '__all__'

            def validate(self, value):
                value = validate_person(value)
                return value

        return MViewSerializer

    return inner_decorator
